import { Injectable } from '@angular/core'
import { Http } from '@angular/http'
import { map, catchError } from 'rxjs/operators'
import { of } from 'rxjs/observable/of'
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'
import { Cookie } from 'ng2-cookies'
import { Store } from '@ngrx/store'
import { AUTH_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME, USER_ID } from '../../common/consts'

import * as fromRoot from '../../core/reducers'
import * as fromUserAction from '../../core/actions/user'

@Injectable()
export class AuthGuard implements CanActivate {
  isLogon: boolean
  constructor (
    private _router: Router,
    private _http: Http,
    private _store: Store<fromRoot.IState>
  ) {
    _store.select(fromRoot.selectIsLogon).subscribe((isLogon) => this.isLogon = isLogon)
  }

  canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (Cookie.check(AUTH_COOKIE_NAME)) {
      if (!this.isLogon) {
        // 强制刷新时
        this._store.dispatch(new fromUserAction.FetchCurrentUserAction())
      }
      return true
    } else {
      const payload = {
        grantType: 'refresh_token',
        refreshToken: Cookie.get(REFRESH_TOKEN_COOKIE_NAME),
        id: localStorage.getItem(USER_ID)
      }

      return this._http.post(`api/user/auth`, payload)
        .pipe(
          map((res) => {
            if (res.status >= 200 && res.status < 300) {
              this._store.dispatch(new fromUserAction.RefreshTokenSuccessAction(res.json()))
            }
            return true
          }),
          catchError(() => {
            this._router.navigate(['/login'])
            return of(false)
          })
        )
    }
  }
}
